package com.newx.test.auth.license;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.newx.auth.license.param.GenerateLicenseRequest;
import com.newx.auth.license.param.ValidateLicenseRequest;
import com.newx.auth.license.tool.CommonResult;
import com.newx.auth.license.tool.KeyPairGeneratorTool;
import com.newx.auth.license.tool.LicenseTool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;

/**
 * @Created by yxl
 * @Date 2025/2/16 8:56
 */
@Api(tags = "许可证管理")
@RestController
@RequestMapping("/license")
public class LicenseController {

    private static final Logger log = LoggerFactory.getLogger(LicenseController.class);
    /**
     * 生成OpenSSL密钥对
     * @param filePath 私钥公钥文件保存路径
     * @return
     * @throws Exception
     */
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "生成OpenSSL密钥对(保存硬盘)")
    @PostMapping("/generatorOpenSSLSavePath")
    public CommonResult generatorOpenSSL(@ApiParam(name = "filePath", value = "私钥公钥文件保存路径") @RequestParam String filePath) throws Exception{
        return CommonResult.success(KeyPairGeneratorTool.generatorOpenSSL(filePath));
    }

    /**
     * 生成OpenSSL密钥对,直接下载
     * @return
     * @throws Exception
     */
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "生成OpenSSL密钥对(直接下载)")
    @GetMapping("/generatorOpenSSLDowload")
    public ResponseEntity<InputStreamResource> generatorOpenSSLDowload() {
        try {
            byte[] zipData = KeyPairGeneratorTool.generateAndPackKeysToZip();
            ByteArrayInputStream bis = new ByteArrayInputStream(zipData);

            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=license.zip");
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(zipData.length)
                    .body(new InputStreamResource(bis));

        } catch (IOException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 生成License文件
     * @return
     * @throws Exception
     */
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "生成License文件(存储硬盘)")
    @PostMapping("/generatorLicense")
    public CommonResult generatorLicense(@RequestBody GenerateLicenseRequest request) throws Exception{
        return CommonResult.success(LicenseTool.generateLicense(request.getPrivateKeyPath(), request.getLicenseFilePath(), request.getValidFrom(), request.getValidEnd()));
    }

    /**
     * 生成License文件,返回字符串
     * @param request
     * @return
     */
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "生成License文件(返回字符串)")
    @PostMapping("/generatorLicenseStr")
    public CommonResult generatorLicenseStr(@RequestBody GenerateLicenseRequest request) throws Exception {
        PrivateKey privateKey = LicenseTool.readPrivateKey(request.getPrivateKeyPath());
        String licenseContent = LicenseTool.generateLicense(
                privateKey,
                request.getValidFrom(),
                request.getValidEnd()
        );
        return CommonResult.success(licenseContent);
    }

    /**
     * 生成License文件,直接下载
     * @param request
     * @return
     */
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "生成License文件(直接下载)")
    @PostMapping("/generatorLicenseDowload")
    public ResponseEntity<InputStreamResource> generateLicense(@RequestBody GenerateLicenseRequest request) {
        try {
            PrivateKey privateKey = LicenseTool.readPrivateKey(request.getPrivateKeyPath());
            String licenseContent = LicenseTool.generateLicense(
                    privateKey,
                    request.getValidFrom(),
                    request.getValidEnd()
            );
            ByteArrayInputStream bis = new ByteArrayInputStream(licenseContent.getBytes());
            // 将licenseContent通过浏览器下载
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=license.lic");
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            log.info("licenseContent: {}", licenseContent);
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(licenseContent.getBytes().length)
                    .body(new InputStreamResource(bis));
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    /**
     * 验证License文件
     * @param publicKeyPath 公钥文件路径
     * @param licenseFilePath license文件路径
     * @return
     * @throws Exception
     */
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "验证License文件(文件路径)")
    @PostMapping("/isValidLicense")
    public CommonResult isValidLicense(String publicKeyPath, String licenseFilePath) throws Exception {
        return CommonResult.success(LicenseTool.isValidLicenseByFile(publicKeyPath, licenseFilePath));
    }

    /**
     * 验证License文件
     * @param request
     * @return
     */
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "验证License文件(文件内容)")
    @PostMapping("/validateLicense")
    public CommonResult validateLicense(@RequestBody ValidateLicenseRequest request) throws Exception {
        return CommonResult.success(LicenseTool.isValidLicenseByContent(
                request.getPublicKeyPath(),
                request.getLicenseContent()
        ));
    }
}
